/*************************************************
Author: byron
Date: 12/27/2012
Description:
Notes: 
*************************************************/

#ifndef __CRandArray_h__
#define __CRandArray_h__

#include "CTArray.h"
#include "CTRandomNum.h"

template<typename T, int COUNT>
class CRandArray : public CTArray<T,COUNT>
{
public:
    CRandArray()
    {
    }

    virtual ~CRandArray()
    {
    }

#define NUM_LONG_LONG_BIT 64

    void SetBit(int64& i64Array, int iIndex)
    {
        if (iIndex < 0 || iIndex >= NUM_LONG_LONG_BIT ||
            CTArray<T,COUNT>::Size() > NUM_LONG_LONG_BIT)
        {
            return;
        }

        int64 i64Tmp = 1;
        i64Array |= (i64Tmp << iIndex);
    }

    bool GetBit(int64& i64Array, int iIndex)
    {
        if (iIndex < 0 || iIndex >= NUM_LONG_LONG_BIT ||
            CTArray<T,COUNT>::Size() > NUM_LONG_LONG_BIT)
        {
            return false;
        }

        int64 i64Tmp = 1;
        return (i64Array & (i64Tmp << iIndex));
    }

#define RAND_COMM_MOD 1000

    void Random()
    {
        T stTemp;
        int iIndex = 0;
        int64 i64Array = 0;
        for (int i = CTArray<T,COUNT>::Size() - 1; i >= 0; --i)
        {
            if (i > 0)
            {
                if (i > 1 && GetBit(i64Array, i))
                {
                    iIndex = CT_RANDOM_NUM->GetRand(RAND_COMM_MOD) % (i + 1);
                }
                else
                {
                    iIndex = CT_RANDOM_NUM->GetRand(RAND_COMM_MOD) % i;
                }

                stTemp = CTArray<T,COUNT>::m_astData[i];
                CTArray<T,COUNT>::m_astData[i] =
                    CTArray<T,COUNT>::m_astData[iIndex];
                CTArray<T,COUNT>::m_astData[iIndex] = stTemp;
                SetBit(i64Array, iIndex);
            }
        }
    }
};

#endif // __CRandArray_h__

